//
//  TokenHistoryViewController.swift
//  GhostWorld
//
//  Created by Kam on 2018/6/18.
//  Copyright © 2018 LKGood. All rights reserved.
//

import UIKit

private let tokenPurchaseCellIdentifier = "TokenPurchaseCell"
private let contentExchangeCellIdentifier = "ContentExchangeCell"
private let vipExchangeCellIdentifier = "VIPExchangeCell"
private let noDataCellIdentifier = "NoDataTableCell"
private let headerIdentifier = "TokenHistoryHeader"

class TokenHistoryViewController: BaseViewController {

  struct HistoryItem {
    var type: String
    var content: String?
    var coinCount: Int
    var image: String?
  }
  struct History {
    var dateString: String
    var items: [HistoryItem]
  }
  
  enum ListType {
    case purchased, exchanged
  }
  
  // MARK: - IBOutlets
  
  @IBOutlet private weak var categoryContainer: UIView!
  @IBOutlet private weak var purchasedButton: UIButton!
  @IBOutlet private weak var exchangedButton: UIButton!
  @IBOutlet private weak var focusLine: UIView!
  @IBOutlet private weak var focusLineLeftConstraint: NSLayoutConstraint!
  @IBOutlet private weak var tableView: UITableView!
  
  // MARK: - Private vars
  
  private var listType: ListType = .purchased
  private var isFirstLoaded = true
  private var purchasedArray: [History]?
  private var exchangedArray: [History]?
  
  // MARK: - Private methods
  
  private func prepareUI() {
    tableView.register(UINib(nibName: noDataCellIdentifier, bundle: nil), forCellReuseIdentifier: noDataCellIdentifier)
    tableView.register(UINib(nibName: headerIdentifier, bundle: nil), forHeaderFooterViewReuseIdentifier: headerIdentifier)
    
    tableView.contentInset = UIEdgeInsets.init(top: 20, left: 0, bottom: 40, right: 0)
    tableView.scrollIndicatorInsets = tableView.contentInset
  }
  
  @objc private func loadData() {
    API.shared.requestAPI (
      APIURLStrings.tokenHistory,
      method: .get,
      header: API.shared.memeberHeader,
      successCallback: { json in
        
        func process(name: String) -> [History]? {
          if let arrayJSON = json[name].array {
            let historyArray = arrayJSON.map { history -> TokenHistoryViewController.History in
              var items = [HistoryItem]()
              if let itemsJSON = history["items"].array {
                items = itemsJSON.map { itemJSON in
                  HistoryItem(
                    type: itemJSON["type"].stringValue,
                    content: itemJSON["content"].string,
                    coinCount: itemJSON["coin_count"].intValue,
                    image: itemJSON["image"].string
                  )
                }
              }
              return History (
                dateString: history["date"].stringValue,
                items: items
              )
            }
            return historyArray
          } else {
            return nil
          }
        }
        
        self.purchasedArray = process(name: "purchased")
        self.exchangedArray = process(name: "exchanged")
        
        self.tableView.reloadData()
        UIView.animate(withDuration: 0.3) {
          self.tableView.alpha = 1
        }
        
    }) { (message, code) in
      loggingPrint("[\(code)]: \(message)")
    }
  }
  
  private func focus(type: ListType) {
    if type != listType {
      listType = type
      UIView.animate(withDuration: 0.3, animations: {
        switch type {
        case .purchased:
          self.purchasedButton.isSelected = true
          self.exchangedButton.isSelected = false
          self.focusLineLeftConstraint.constant = 0
        case .exchanged:
          self.purchasedButton.isSelected = false
          self.exchangedButton.isSelected = true
          self.focusLineLeftConstraint.constant = self.categoryContainer.width / 2
        }
        self.view.layoutIfNeeded()
        self.tableView.alpha = 0
      }) { _ in
        self.tableView.reloadData()
        UIView.animate(withDuration: 0.3) {
          self.tableView.alpha = 1
        }
      }
    }
  }
  
  private func getDisplayList() -> [History]? {
    return (listType == .purchased ? purchasedArray : exchangedArray)
  }
  
  private func addNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: .uploadTokenPurchaseInfoSuccess, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: .tokenExchangeSuccess, object: nil)
  }
  
  // MARK: - Public vars
  
  
  
  // MARK: - Lifecycle
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    addNotifications()
    prepareUI()
    loadData()
  }
  
  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if isFirstLoaded {
      tableView.alpha = 0
    }
  }
  
  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    if isFirstLoaded {
      isFirstLoaded = false
    }
  }
  
  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  
  deinit {
    NotificationCenter.default.removeObserver(self)
  }
  // MARK: - IBActions
  
  @IBAction func changeTypeToPurchased() {
    focus(type: .purchased)
  }
  
  @IBAction func changeTypeToExchanged() {
    focus(type: .exchanged)
  }
  
  // MARK: - Public methods
  
  
}

// MARK: - UITableViewDataSourse

extension TokenHistoryViewController: UITableViewDataSource {
  func numberOfSections(in tableView: UITableView) -> Int {
    let historyArray = getDisplayList()
    if let count = historyArray?.count, count > 0 {
      return count
    } else {
      return 1
    }
  }
  
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let historyArray = getDisplayList()
    if let count = historyArray?.count, count > 0 {
      let items = historyArray![section].items
      if items.count > 0 {
        return items.count
      } else {
        return 1
      }
    } else {
      return 1
    }
  }
  
  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    func getNoDataCell() -> NoDataTableCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: noDataCellIdentifier, for: indexPath) as! NoDataTableCell
      cell.tipLabel.text = "没有数据"
      return cell
    }
    
    let historyArray = getDisplayList()
    if let count = historyArray?.count, count > 0 {
      let items = historyArray![indexPath.section].items
      if items.count > 0 {
        // history cell
        let item = items[indexPath.row]
        switch item.type {
        case "purchase":
          let cell = tableView.dequeueReusableCell(withIdentifier: tokenPurchaseCellIdentifier, for: indexPath) as! TokenPurchaseCell
          cell.countLabel.text = "\(item.coinCount) ×"
          return cell
        case "group", "album":
          let cell = tableView.dequeueReusableCell(withIdentifier: contentExchangeCellIdentifier, for: indexPath) as! ContentExchangeCell
          cell.contentLabel.text = item.content!
          cell.countLabel.text = "\(item.coinCount) ×"
          if let url = URL(string: APIURLStrings.imagePrefix + item.image!) {
            cell.coverImageView.af_setImage(withURL: url)
          }
          return cell
        case "premium":
          let cell = tableView.dequeueReusableCell(withIdentifier: vipExchangeCellIdentifier, for: indexPath) as! VIPExchangeCell
          cell.countLabel.text = "\(item.coinCount) ×"
          return cell
        default:
          return getNoDataCell()
        }
      } else {
        // no data cell
        return getNoDataCell()
      }
    } else {
      // no data cell
      return getNoDataCell()
    }
  }
  
  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerIdentifier) as! TokenHistoryHeader
    let historyArray = getDisplayList()
    if  historyArray?.count ?? 0 > section,
        let history = historyArray?[section],
       let date = Date(fromString: history.dateString, format: .dateTime){
      header.dateLabel.text = date.toString(format: .dateWithChinese)
    }
    else {
      header.dateLabel.text = "某一天"
    }
    return header
  }
}

extension TokenHistoryViewController: UITableViewDelegate {
  func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return TokenHistoryHeader.defaultHeight
  }
  
  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let historyArray = getDisplayList()
    if let count = historyArray?.count, count > 0 {
      let items = historyArray![indexPath.section].items
      if items.count > 0 {
        // history cell
        let item = items[indexPath.row]
        switch item.type {
        case "purchase":
          return TokenPurchaseCell.defaultHeight
        case "group", "album":
          return ContentExchangeCell.defaultHeight
        case "premium":
          return VIPExchangeCell.defaultHeight
        default:
          return NoDataTableCell.defaultHeight
        }
      } else {
        return NoDataTableCell.defaultHeight
      }
    } else {
      return NoDataTableCell.defaultHeight
    }
  }
}
